home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright Cornell University 1986. All rights are reserved.
-
- gethost.c contains the dialog used to get a host name/address from
- the user and maintain the associated database.
-
- */
-
- #include <em.h>
-
- #include <list.h>
-
- #include <config.h>
-
- #include <h19.h>
- #include <resdefs.h>
- #include <menudefs.h>
-
- #include <net.h> /* merged TCP */
- #ifdef DUALTCP
- #endif
-
- #ifdef MACTCP
- #include <MacTCPCommonTypes.h>
- #include <AddressXlation.h>
-
- #else
-
- #include <tcp.h>
- #include <tcpdefs.h>
- #endif
-
- extern char * malloc();
-
- extern unsigned long mtdnresolve();
-
- long nameresolved;
-
- #define LASTHOSTID 0
-
-
- extern char * index();
-
- /* See permission and disclaimer notice in file "notice.h" */
-
-
- /* resolve_name.c */
-
- /* Resolve a host name into an internet address. Three name formats are
- * accepted:
- * 1) A character string host name
- * 2) An octal host number, in the form:
- * <net>,<subnet>,<rsd>,<host>
- * or a decimal host number, in the form:
- * <net>.<subnet>.<rsd>.<host>
- * Any of the <net>, <subnet>, and <rsd> may be left blank or left out
- * entirely; they default to the local net/subnet.
- * 3) A thirty-two bit hex number, preceeded by a '#', which is used
- * without interpretation as the host number.
- * If a character string name is supplied, it is first looked up in a
- * local host table. If it is not found there, the routine goes off to
- * internet name servers to try to resolve the name.
- *
- * The following routines are included in this file:
- * resolve_name Resolve a name as specified above
- * gethmch Parse a hex machine address specification
- * getomch Parse an octal machine address specification
- * The routines which use the internet name server are in the file
- * name_user.c.
- */
-
-
- #define INSZ 4
-
- extern char *index();
-
- /* Resolve foreign host internet address
- * Scan table of host names and nicknames.
- * For each name, see if our string is a prefix. If so, keep checking -
- * could be ambiguous.
- * If ambiguous, return 0.
- * When find no matches, try internet name servers.
- *
- * Arguments:
- */
-
- resolve_name(name, hsockp)
- char *name;
- struct hostsock * hsockp;
- {
- char tname[100];
- char taddr[100];
- unsigned int port;
- int hostconnact;
- int sockargs;
- int dotargs;
- short dotseen = FALSE;
- unsigned char * namep;
-
- if (strlen(name) == 0) {
- error("No address given");
- return(-1);
- }
-
- if ((name[0] >= '0') && (name[0] <= '9')) {
- /* leading numeral indicates an internet address using dot notation */
- if (getdmch(name, hsockp)) {
- error(badaddress);
- return(-1);
- }
- }
- else if (name[0] == '#') {
- /* leading '#' indicates hex address */
- if (gethmch(name, hsockp)) {
- error(badaddress);
- return(-1);
- }
- }
- else if (emdp->conntype == CONN_MACTCP) {
- /* a string, hand it to the domain name resolver */
- /* first parse the socket number which is "..300" format */
-
- hsockp->port = TELNETSOCK;
-
- sockargs = sscanf(name, "%s", &tname[0]);
- dotargs = 0;
- namep = &tname[0];
- while (*namep) {
- if (*namep == '.') {
- if (dotseen) {
- /* double dot is end of host name, beginning of socket */
- --namep;
- *namep = '\0'; /* terminate the string at first dot */
- namep += 2; /* skip the dots */
- dotargs = sscanf(namep, "%d;%d", &port, &hostconnact);
- }
- dotseen = TRUE;
- }
- else
- dotseen = FALSE;
- namep++;
- }
-
- /* we presume this is an IP Domain Name if it doesn't match
- any of the above constants, so we try the DNR */
-
- if ((hsockp->u.addr = mtdnresolve(&tname[0])) == 0)
- return(-1);
-
- if (hsockp->u.addr == -1)
- /* prevent attempts to open a session with the broadcast address -1 ... */
- return(-1);
-
- /* now set the socket and id portions */
- if (dotargs >= 1 && port != 0)
- hsockp->port = port;
- else
- hsockp->port = TELNETSOCK;
-
- if (dotargs == 2)
- hsockp->hostconnact = hostconnact;
- else
- hsockp->hostconnact = -1;
- }
- else {
- /* old TCP can't handle DNR */
- error("Cornell TCP can't resolve domain names");
- hsockp->u.addr = -1L;
- return(-1);
- }
- return(0);
- }
-
-
- /* Parse foreign host number input as hex string */
-
- gethmch(name, hsockp)
- register char *name;
- struct hostsock * hsockp;
- {
- register char *tmp;
- register int i;
- union {
- char bytes[INSZ];
- long name;
- } addr;
-
- tmp = &name[1];
- for (i = 0; i < 8; i++) {
- if ((*tmp >= '0') && (*tmp <= '9'))
- *tmp++ -= '0';
- else if ((*tmp >= 'A') && (*tmp <= 'Z'))
- *tmp++ -= ('A' - 10);
- else if ((*tmp >= 'a') && (*tmp <= 'z'))
- *tmp++ -= ('a' - 10);
- else {
- hsockp->u.addr = -1L;
- return(-1);
- }
- }
-
- if (*tmp != 0) {
- hsockp->u.addr = -1L;
- return(-1);
- }
-
- tmp = &name[1];
- for (i = 0; i < INSZ; i++)
- addr.bytes[i] = ((*tmp++ << 4) + *tmp++);
- hsockp->u.addr = addr.name;
- return(0);
- }
-
-
- /* Parse foreign host number input as decimal string, placing host socket in hsockp */
-
- getdmch(name, hsockp)
- char *name;
- struct hostsock * hsockp;
- {
- unsigned int addr[4];
- unsigned int port;
- int hostconnact;
- register char thechar;
- register char * tempp;
- int sockargs;
- int ipargs;
- int count;
- int addrb; /* counter for accessing the bytes in the addr backwards */
-
- sockargs = 0;
-
- hsockp->u.addr = rnet->ip_addr;
- hsockp->port = 0;
- hsockp->hostconnact = 0;
- /* reset hostsock struct */
-
- /* if a ".." is in the string, a socket comes after it;
- interpret the socket as a decimal #
- if a ';' occurs in the address, it indicates a string ID for connect
- actions
- */
- ipargs = sscanf(name, "%d.%d.%d.%d", &addr[0], &addr[1],
- &addr[2], &addr[3]);
-
- for (count = ipargs, addrb = 3; --count >= 0; --addrb) {
- /* spot bad addresses for 1-4 */
- if (addr[count] < 0 || addr[count] > 256) {
- hsockp->u.addr = -1L;
- return(-1);
- }
- hsockp->u.bytes[addrb] = addr[count];
- }
-
- /* we got the IP address, get the rest */
- sockargs = sscanf(name, "%d.%d.%d.%d..%d;%d", &addr[0], &addr[1],
- &addr[2], &addr[3], &port, &hostconnact);
-
- /* now set the socket as desired */
- if (sockargs >= 5 && port != 0)
- hsockp->port = port;
- else
- hsockp->port = TELNETSOCK;
-
- if (sockargs == 6)
- hsockp->hostconnact = hostconnact;
- else
- hsockp->hostconnact = -1;
-
- return(0);
- }
-
-
- #ifdef MACTCP
-
-
- extern unsigned long getmyA5();
- pascal void resolved();
-
- unsigned long mtdnresolve(tname)
- char * tname; /* hostname */
- {
- struct hostInfo hostinfo;
-
- if (!macipopen) {
- /* open the MacTCP driver if not open TODO this won't handle async */
- if (macip_init())
- return(-1);
- }
- /* open the DNR */
- if (OpenResolver(NULL)) {
- error("Can't open MacTCP Domain Name Resolver");
- return(-1);
- }
-
- /* call the DNR */
- /*
- char * mtcpresolvewait = "\r\r Getting host address from domain name server...";
-
- fillwindow(COPYWINDOW, mtcpresolvewait, (long) strlen(mtcpresolvewait), systemFont, 12, (long) -1);
-
- for some reason this induces mactcp to crash!
- */
- SetCursor(*GetCursor(watchCursor));
- /* put up a watch cursor to show this may take some time */
-
- nameresolved = 0;
-
- StrToAddr(tname, &hostinfo, resolved, NULL);
- while (!nameresolved) {
- short thechar;
- EventRecord evt;
-
- /* check to see if the user wants to abort, because mactcp's dnr
- sometimes hangs... */
- GetNextEvent(keyDownMask|autoKeyMask, &evt);
- if (evt.what == keyDown || evt.what == autoKey) {
- thechar = evt.message & 0xff;
- if (evt.modifiers & cmdKey) {
- if (thechar == '.') {
- error("Interrupting the MacTCP domain name resolver may be hazardous; you should probably reboot your machine");
- break;
- }
- }
- }
- bkrd_service();
- }
-
- SetCursor(&arrow);
-
- /*
- fillwindclose();
- */
- CloseResolver();
- if (nameresolved != 1) {
- switch (nameresolved) {
- case nameSyntaxErr:
- error("MacTCP resolver: invalid name syntax");
- break;
- case cacheFault:
- error("MacTCP resolver: no answer from nameserver");
- /* error("MacTCP resolver: cache fault"); */
- break;
- case noResultProc:
- error("MacTCP resolver: no result proc");
- break;
- case noNameServer:
- error("MacTCP resolver: can't find name server");
- break;
- case authNameErr:
- error("MacTCP resolver: auth. name error");
- break;
- case noAnsErr:
- error("MacTCP resolver: no answer from nameserver");
- break;
- case dnrErr:
- error("MacTCP resolver: error in domain name resolver");
- break;
- }
- }
- return(hostinfo.addr[0]);
- }
-
-
- /* DNR.c - DNR library for MPW
-
- (c) Copyright 1988 by Apple Computer. All rights reserved
-
- */
-
-
- #include <errors.h>
-
- #define OPENRESOLVER 1
- #define CLOSERESOLVER 2
- #define STRTOADDR 3
- #define ADDRTOSTR 4
- #define ENUMCACHE 5
- #define ADDRTONAME 6
- #define HINFO 7
- #define MXINFO 8
-
- Handle codeHndl = NULL;
-
- OSErrProcPtr dnr = NULL;
-
- #define OLDDNR
- #ifdef OLDDNR
-
- /* OpenOurRF is called to open the MacTCP driver resources */
-
- short OpenOurRF()
- {
- HPrmBlkRec fi;
- Str255 filename;
- #define ZBEN
- #ifdef ZBEN /* ! */
- short savevol; /* ! */
- OSErr status; /* ! */
- extern SysEnvRec environs;
- #endif /* ! */
-
- fi.ioCompletion = NULL;
- fi.ioNamePtr = &filename;
- fi.ioVRefNum = environs.sysVRefNum;
- fi.u.hfp.ioDirID = 0;
- fi.u.hfp.ioFDirIndex = 1;
-
- while (PBHGetFInfo(&fi, (Boolean) FALSE) == noErr) {
- /* scan system folder for driver resource files of specific type & creator */
- if (fi.u.hfp.ioFlFndrInfo.fdType == 'cdev' &&
- fi.u.hfp.ioFlFndrInfo.fdCreator == 'mtcp') {
- /* found the MacTCP driver file */
- #ifdef ZBEN
- /* a fix courtesy of usenet to the DNR,
- which will fail to get the resource it wants
- if it's not on the main Volume (another PMSP-related
- problem
- */
-
- /* ! */
- GetVol((StringPtr) NULL,&savevol); /* ! */
- SetVol((StringPtr) NULL,environs.sysVRefNum); /* ! */
- status = OpenResFile(&filename); /* ! */
- SetVol((StringPtr) NULL,savevol); /* ! */
- return(status); /* ! */
- #else /* ! */
- return(OpenResFile(&filename));
- #endif
- }
- /* check next file in system folder */
- fi.u.hfp.ioFDirIndex++;
- fi.u.hfp.ioDirID = 0;
- }
- return(-1);
- }
-
-
- OSErr OpenResolver(fileName)
- char *fileName;
- {
- short refnum;
- OSErr rc;
-
- if (dnr != NULL)
- /* resolver already loaded in */
- return(noErr);
-
- /* open the MacTCP driver to get DNR resources. Search for it based on
- creator & type rather than simply file name */
- refnum = OpenOurRF();
-
- /* ignore failures since the resource may have been installed in the
- System file if running on a Mac 512Ke */
-
- /* load in the DNR resource package */
- codeHndl = GetIndResource('dnrp', 1);
- if (codeHndl == NULL) {
- /* can't open DNR */
- return(ResError());
- }
-
- DetachResource(codeHndl);
- if (refnum != -1) {
- CloseResFile(refnum);
- }
-
- /* lock the DNR resource since it cannot be reloated while opened */
- HLock(codeHndl);
- dnr = (OSErrProcPtr) *codeHndl;
-
- /* call open resolver */
- rc = (*dnr)((long) OPENRESOLVER, fileName);
- if (rc != noErr) {
- /* problem with open resolver, flush it */
- HUnlock(codeHndl);
- DisposHandle(codeHndl);
- dnr = NULL;
- }
- return(rc);
- }
-
- #else
- /* use the stuff provided with MacTCP 1.1B1, which adds Sys 7.0-stuff */
-
- TrapType GetTrapType(theTrap)
- unsigned long theTrap;
- {
- if (BitAnd(theTrap, 0x0800) > 0)
- return(ToolTrap);
- else
- return(OSTrap);
- }
-
-
-
- Boolean TrapAvailable(trap)
- unsigned long trap;
- {
- TrapType trapType = ToolTrap;
- unsigned long numToolBoxTraps;
-
- if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- numToolBoxTraps = 0x200;
- else
- numToolBoxTraps = 0x400;
-
- trapType = GetTrapType(trap);
- if (trapType == ToolTrap) {
- trap = BitAnd(trap, 0x07FF);
- if (trap >= numToolBoxTraps)
- trap = _Unimplemented;
- }
- return(NGetTrapAddress(trap, trapType) != NGetTrapAddress(_Unimplemented, ToolTrap));
-
- }
-
- short GetCPanelFolder()
- {
- short vRefNum = 0;
- long dirID = 0;
- SysEnvRec info;
- Boolean hasFolderMgr = (Boolean) FALSE;
- long feature;
- short wdRef;
-
- if (TrapAvailable(_GestaltDispatch))
- if (Gestalt(gestaltFindFolderAttr, &feature) == noErr)
- hasFolderMgr = (Boolean) TRUE;
- if (!hasFolderMgr) {
- SysEnvirons(1, &info);
- return(info.sysVRefNum);
- }
- else {
- if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, &vRefNum, &dirID) != noErr)
- return(0);
- if (OpenWD(vRefNum, dirID, 'dnrp', &wdRef) == noErr)
- return(wdRef);
- else
- return(0);
- }
- }
-
- /* OpenOurRF is called to open the MacTCP driver resources */
-
- short OpenOurRF()
- {
- ParamBlockRec fi;
- Str255 filename;
- short vRefNum;
-
- vRefNum = GetCPanelFolder();
- fi.fileParam.ioCompletion = NULL;
- fi.fileParam.ioNamePtr = &filename;
- fi.fileParam.ioVRefNum = vRefNum;
- fi.fileParam.ioFDirIndex = 1;
-
- while (PBGetFInfo(&fi, (Boolean) FALSE) == noErr) {
- /* scan system folder for driver resource files of specific type & creator */
- if (fi.fileParam.ioFlFndrInfo.fdType == 'cdev' &&
- fi.fileParam.ioFlFndrInfo.fdCreator == 'ztcp') {
- /* found the MacTCP driver file */
- return(OpenRFPerm(&filename, vRefNum, fsRdPerm));
- }
- /* check next file in system folder */
- fi.fileParam.ioFDirIndex++;
- }
- return(-1);
- }
-
-
- OSErr OpenResolver(fileName)
- char *fileName;
- {
- short refnum;
- OSErr rc;
-
- if (dnr != NULL)
- /* resolver already loaded in */
- return(noErr);
-
- /* open the MacTCP driver to get DNR resources. Search for it based on
- creator & type rather than simply file name */
- refnum = OpenOurRF();
-
- /* ignore failures since the resource may have been installed in the
- System file if running on a Mac 512Ke */
-
- /* load in the DNR resource package */
- codeHndl = GetIndResource('dnrp', 1);
- if (codeHndl == NULL) {
- /* can't open DNR */
- return(ResError());
- }
-
- DetachResource(codeHndl);
- if (refnum != -1) {
- CloseWD(refnum);
- CloseResFile(refnum);
- }
-
- /* lock the DNR resource since it cannot be reloated while opened */
- HLock(codeHndl);
- dnr = (OSErrProcPtr) *codeHndl;
-
- /* call open resolver */
- rc = (*dnr)((long) OPENRESOLVER, fileName);
- if (rc != noErr) {
- /* problem with open resolver, flush it */
- HUnlock(codeHndl);
- DisposHandle(codeHndl);
- dnr = NULL;
- }
- return(rc);
- }
-
-
- #endif
-
-
- OSErr CloseResolver()
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- /* call close resolver */
- (void) (*dnr)((long) CLOSERESOLVER);
-
- /* release the DNR resource package */
- HUnlock(codeHndl);
- DisposHandle(codeHndl);
- dnr = NULL;
- return(noErr);
- }
-
- OSErr StrToAddr(hostName, rtnStruct, resultproc, userDataPtr)
- char *hostName;
- struct hostInfo *rtnStruct;
- long resultproc;
- char *userDataPtr;
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- return((*dnr)((long) STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
- }
-
- OSErr AddrToStr(addr, addrStr)
- unsigned long addr;
- char *addrStr;
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- (*dnr)((long) ADDRTOSTR, addr, addrStr);
- return(noErr);
- }
-
- OSErr EnumCache(resultproc, userDataPtr)
- long resultproc;
- char *userDataPtr;
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- return((*dnr)((long) ENUMCACHE, resultproc, userDataPtr));
- }
-
-
- OSErr AddrToName(addr, rtnStruct, resultproc, userDataPtr)
- unsigned long addr;
- struct hostInfo *rtnStruct;
- long resultproc;
- char *userDataPtr;
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- return((*dnr)((long) ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
- }
-
- OSErr HInfo(hostName, returnRecPtr, resultProc, userDataPtr)
- char *hostName;
- struct returnRec *returnRecPtr;
- long resultProc;
- char *userDataPtr;
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- return((*dnr)((long) HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
-
- }
-
- OSErr MXInfo(hostName, returnRecPtr, resultProc, userDataPtr)
- char *hostName;
- struct returnRec *returnRecPtr;
- long resultProc;
- char *userDataPtr;
- {
- if (dnr == NULL)
- /* resolver not loaded error */
- return(notOpenErr);
-
- return((*dnr)((long) MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
-
- }
-
- pascal void resolved(hostinfo, userdata)
- struct hostInfo * hostinfo;
- char * userdata;
- {
- unsigned long oldA5;
-
- oldA5 = getmyA5();
-
- nameresolved = hostinfo->rtnCode;
- switch (hostinfo->rtnCode) {
- case 0: {
- /* OK, I presume */
- nameresolved = 1;
- setA5(oldA5);
- return;
- }
- case cacheFault: {
- /* address not in cache, wait for resolver */
- setA5(oldA5);
- return;
- }
- }
- setA5(oldA5);
- }
- #endif
-
-
- /* save host address resource (a C string) in the current resource file */
-
- savehostres(twp)
- struct winds * twp;
- {
- long len;
- Handle ohlasthost;
-
- if (twp->hlasthost == NULL)
- return(-1);
-
- ohlasthost = twp->hlasthost;
-
- if ( (twp->hlasthost = Get1Resource('LHST', LASTHOSTID) ) != NULL) {
- killhost(twp);
- }
- len = GetHandleSize(ohlasthost);
- twp->hlasthost = NewHandle((long) len);
- strcpy(*twp->hlasthost, *ohlasthost);
-
- DisposHandle(ohlasthost);
-
- AddResource(twp->hlasthost, 'LHST', LASTHOSTID, "\P");
- if (ResError()) {
- error("Can't save TCP/IP Address");
- return(-1);
- }
- else {
- UpdateResFile(HomeResFile(twp->hlasthost));
- DetachResource(twp->hlasthost);
- }
- }
-
-
- killhost(twp)
- struct winds * twp;
- {
- int hhosthome;
-
- hhosthome = HomeResFile(twp->hlasthost);
- RmveResource(twp->hlasthost);
- if (ResError())
- error("No host name resource kill");
-
- UpdateResFile(hhosthome);
- DisposHandle(twp->hlasthost);
- }
-
-